package com.geovis.emergency.spd.biz.pc.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.geovis.emergency.spd.biz.pc.service.*;
import com.geovis.emergency.spd.entity.mobile.pojo.vo.PcDrillPlanTaskStatisticsVO;
import com.geovis.emergency.spd.entity.pc.entity.*;
import com.geovis.emergency.spd.entity.pc.pojo.enums.DrillTypeEnum;
import com.geovis.emergency.spd.entity.pc.pojo.enums.TaskStatusEnum;
import com.geovis.emergency.spd.entity.pc.pojo.vo.DrillReportVO;
import com.geovis.emergency.spd.entity.pc.pojo.vo.DrillStatisticsVO;
import com.geovis.emergency.spd.util.Util;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 演练统计 服务实现类
 * </p>
 *
 * @author Lonsho
 * @version 1.0
 * @date 2022/7/28
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class DrillStatisticsServiceImpl implements IDrillStatisticsService {

    private final IPcDrillService pcDrillService;
    private final IPcDrillDisasterService pcDrillDisasterService;
    private final IPcDrillDutyUserService pcDrillDutyUserService;
    private final IPcDrillPlanTaskService pcDrillPlanTaskService;
    private final IPcDrillPlanTaskStatisticsService pcDrillPlanTaskStatisticsService;
    private final IPcPlanService pcPlanService;

    @Override
    public DrillReportVO drillStatistics(String drillId) {
        PcDrill pcDrill = pcDrillService.getById(drillId);
        String time = "--";
        if (ObjectUtil.isNotNull(pcDrill.getStartTime()) && ObjectUtil.isNotNull(pcDrill.getEndTime())){
            long timeDiff = DateUtil.between(DateUtil.date(pcDrill.getStartTime()), DateUtil.date(pcDrill.getEndTime()), DateUnit.MINUTE);
            time = Util.formatMinute(timeDiff);
        }
        long eventCount = pcDrillDisasterService.count(
                Wrappers.lambdaQuery(PcDrillDisaster.class)
                        .eq(PcDrillDisaster::getPcDrillId, drillId)
        );
        List<PcDrillDutyUser> list = pcDrillDutyUserService.list(
                Wrappers.lambdaQuery(PcDrillDutyUser.class)
                        .select(PcDrillDutyUser::getDeptId)
                        .eq(PcDrillDutyUser::getPcDrillId, drillId)
                        .groupBy(PcDrillDutyUser::getDeptId)
        );
        String generalSummary = StrUtil.format("演练总耗时{}，包括{}个应急事件，参与单位{}个。",time,eventCount,list.size());
        List<String> taskList = pcDrillPlanTaskService.list(
                Wrappers.lambdaQuery(PcDrillPlanTask.class)
                        .select(PcDrillPlanTask::getId)
                        .eq(PcDrillPlanTask::getStatus, TaskStatusEnum.PASS.getCode())
                        .eq(PcDrillPlanTask::getPcDrillId, drillId)
        ).stream().map(PcDrillPlanTask::getId).collect(Collectors.toList());
        List<PcDrillPlanTaskStatisticsVO> statisticsVoList = Lists.newArrayList();
        if (CollUtil.isNotEmpty(taskList)){
            List<PcDrillPlanTaskStatistics> statisticsList = pcDrillPlanTaskStatisticsService.list(
                    Wrappers.lambdaQuery(PcDrillPlanTaskStatistics.class)
                            .in(PcDrillPlanTaskStatistics::getPcDrillPlanTaskId, taskList)
            );
            if(CollectionUtils.isEmpty(statisticsList))
            {
                DrillStatisticsVO vo=new DrillStatisticsVO();
                List<PcDrillPlanTaskStatisticsVO> taskStatistics=new ArrayList<>();
                PcDrillPlanTaskStatisticsVO sw=new PcDrillPlanTaskStatisticsVO();
                sw.setStatisticsType("死亡人数");
                sw.setStatisticsCount(0);

                PcDrillPlanTaskStatisticsVO ss=new PcDrillPlanTaskStatisticsVO();
                ss.setStatisticsType("受伤人数");
                ss.setStatisticsCount(0);

                PcDrillPlanTaskStatisticsVO sl=new PcDrillPlanTaskStatisticsVO();
                sl.setStatisticsType("失联人数");
                sl.setStatisticsCount(0);

                PcDrillPlanTaskStatisticsVO ssrs=new PcDrillPlanTaskStatisticsVO();
                sl.setStatisticsType("疏散人数");
                sl.setStatisticsCount(0);

                taskStatistics.add(sw);
                taskStatistics.add(ss);
                taskStatistics.add(sl);
                taskStatistics.add(ssrs);
                vo.setTaskStatistics(taskStatistics);
            }else
            {
                Map<String, List<PcDrillPlanTaskStatistics>> stringListMap = IterUtil.toListMap(statisticsList, PcDrillPlanTaskStatistics::getStatisticsType);
                for (Map.Entry<String, List<PcDrillPlanTaskStatistics>> entry : stringListMap.entrySet()) {
                    PcDrillPlanTaskStatisticsVO pcDrillPlanTaskStatisticsVO = new PcDrillPlanTaskStatisticsVO();
                    pcDrillPlanTaskStatisticsVO.setStatisticsType(entry.getKey());
                    pcDrillPlanTaskStatisticsVO.setStatisticsCount(entry.getValue().stream().mapToInt(PcDrillPlanTaskStatistics::getStatisticsCount).sum());
                    statisticsVoList.add(pcDrillPlanTaskStatisticsVO);
                }
            }

        }
        DrillReportVO drillReportVO = new DrillReportVO()
                .setDrillName(pcDrill.getName());
        if(DrillTypeEnum.EMERGENCY_COMMAND.getCode().equals(pcDrill.getDrillType())){
            drillReportVO.setDrillType(DrillTypeEnum.EMERGENCY_COMMAND.getMsg());
        }else {
            drillReportVO.setDrillType(DrillTypeEnum.PLANNING_DRILL.getMsg());
        }
        if (ObjectUtil.isNotNull(pcDrill.getStartTime())){
            drillReportVO.setStartTime(DateUtil.format(pcDrill.getStartTime(),"yyyy-MM-dd"));
        }else {
            drillReportVO.setStartTime("--");
        }
        if (ObjectUtil.isNotNull(pcDrill.getEndTime())){
            drillReportVO.setEndTime(DateUtil.format(pcDrill.getEndTime(),"yyyy-MM-dd"));
        }else {
            drillReportVO.setEndTime("--");
        }
        if(StrUtil.isNotBlank(pcDrill.getPcPlanId())){
            PcPlan pcPlan = pcPlanService.getById(pcDrill.getPcPlanId());
            if (ObjectUtil.isNotNull(pcPlan)){
                drillReportVO.setPlanName(pcPlan.getTitle());
            }
        }
        drillReportVO.setTaskStatistics(statisticsVoList);
        drillReportVO.setGeneralSummary(generalSummary);
        return drillReportVO;

    }
}
